/*
 * Description: 用于封装socket，提供基础通信能力。
 */
#ifndef GUEST_LINK_SOCKET_H
#define GUEST_LINK_SOCKET_H

#include <map>
#include <mutex>
#include <memory>
#include <string>
#include <atomic>
#include <vector>
#include <iostream>
#include "connect_common.h"
#include "error.h"
#include "common.h"

namespace COMMON {
constexpr int LISTEN_MAX_NUM = 64;
constexpr int EVENT_WAIT_MAX_NUM = 64;
constexpr int EVENT_TIMEOUT = 500;
constexpr int CONNECT_TIMEOUT = 1000 * 100;
constexpr int RETRY_NUMBER = 100;
constexpr int CONNECT_TIME = 10;
constexpr int DEFAULT_BUFSIZE = 3 * 1024 * 1024;
constexpr int RECEIVE_DELAY_TIME = 3; // 接收延时3ms

enum class EVENT_TYPE {
    EVENT_CONNECT = 0,
    EVENT_READ,
    EVENT_DISCONNECT,
    EVENT_CONNECT_SERIAL,
    EVENT_TYPE_MAX
};
constexpr int EVENT_ENUM_NUM = static_cast<int>(EVENT_TYPE::EVENT_TYPE_MAX);

enum class SOCK_TYPE {
    SOCK_SERVER = 0,
    SOCK_CLIENT,
    SOCK_SERIAL,
    SOCK_MAX
};

struct SockAddr {
    LinkType linkType;
    std::string strAddr;
    uint32_t ip;
    uint16_t port;
};

struct MsgSockInfo {
    int sockFd;
    SockAddr localAddr;
    SockAddr remoteAddr;
};


class MsgSock {
public:
    MsgSock();
    ~MsgSock();
    MsgSock(const MsgSock &) = delete;
    MsgSock &operator=(const MsgSock &) = delete;
    /* 返回0(成功)-1(失败) */
    int Create(SocketInfo info, int maxNum = LISTEN_MAX_NUM);
    int Close();
    /* 仅服务端有效 */
    std::shared_ptr<MsgSock> AcceptEx(void);

    int WindowsSend(const void *buffer, uint32_t len);
    int WindowsRecv(void *buffer, uint32_t len, const uint32_t timeout = COMMON::OK); // 接收超时 timeout 单位s
    int GetInfo(void* buf, size_t* size);
    int GetInfoTest();

    int Send(const void *buffer, uint32_t len);
    int Recv(void *buffer, uint32_t len, const uint32_t timeout = COMMON::OK); // 接收超时 timeout 单位s
    void Destroy();
    MsgSockInfo GetSockInfo();
    void SetRecvTimeout(uint32_t timeout) const;
private:
    int SerialInit(SocketInfo info, int timeout);
    // 当前默认值为true，用于异步发消息，false为同步发消息
    int WindowsSerialInit(int port, int timeout, bool ovrl = true);
    int WindowsClose();
    bool isOverlapped = true;

    void *m_hDevice = nullptr;
    std::mutex m_sendMutex = {};
    std::mutex m_recvMutex = {};
    int m_sockFd = INVALID_FD;
    SOCK_TYPE sockType = SOCK_TYPE::SOCK_MAX;
    int listenNum = COMMON::DEFAULT_ERROR;
    SockAddr m_localAddr = {};
    SockAddr m_remoteAddr = {};
};
}
#endif // GUEST_LINK_SOCKET_H
